﻿// Extensions Made Easy - Copyright 2012 by Jan Van der Haegen - All rights reserved, use for educational purposes only.
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using ExtensionsMadeEasy.ClientAPI.Utilities.Base;
using ExtensionsMadeEasy.ClientAPI.Utilities.Extensions;
using Microsoft.LightSwitch.BaseServices.Notifications;
using Microsoft.LightSwitch.Runtime.Shell.ViewModels.Notifications;
using Microsoft.VisualStudio.ExtensibilityHosting;

namespace ExtensionsMadeEasy.Navigation
{
    [Export(typeof(IRecentlySelectedScreenNavigator))]
    public sealed class RecentlySelectedScreenNavigator : NotifyPropertyChangedBase, IRecentlySelectedScreenNavigator
    {
        private string expectedScreen;
        private List<string> screens;
        private int currentIndex;
        
        private readonly IScreenOpener screenOpener;

        public List<string> Screens
        {
            get
            {
                if (this.screens == null)
                {
                    this.screens = new List<string>();
                }
                return this.screens;
            }
            set
            {
                this.screens = value;
            }
        }

        public void Expect(string screen)
        {
            this.expectedScreen = screen;
        }

        public RecentlySelectedScreenNavigator()
        {
            this.screenOpener = VsExportProviderService.GetExportedValue<IScreenOpener>();
            this.GetServiceProxy().NotificationService.Subscribe(typeof(ScreenSelectionChangedNotification), this.OnScreenSelectionChanged);
        }

        public void OnScreenSelectionChanged(Notification n)
        {
            ScreenSelectionChangedNotification notification = n as ScreenSelectionChangedNotification;
            if (notification.SelectedScreen != null)
            {
                if (this.expectedScreen != notification.SelectedScreen.Name)
                {
                    this.processSelectedScreen(notification.SelectedScreen.Name);
                }
                this.Refresh();
            }
        }

        private void processSelectedScreen(string screen)
        {
            if (this.currentIndex != 0)
            {
                this.Screens.RemoveRange(0, this.currentIndex);
                this.currentIndex = 0;
            }
            this.Screens.Insert(0, screen);
        }

        public bool CanNavigateForward
        {
            get
            {
                return this.currentIndex > 0;
            }
        }
        public void NavigateForward()
        {
            if (this.CanNavigateForward)
            {
                string nextScreen = this.Screens[--this.currentIndex];
                this.Expect(nextScreen);
                this.screenOpener.NavigateTo(nextScreen);
            }
        }

        public bool CanNavigateBackward
        {
            get
            {
                return this.currentIndex < this.Screens.Count - 1;
            }
        }
        public void NavigateBackward()
        {
            if (this.CanNavigateBackward)
            {
                string nextScreen = this.Screens[++this.currentIndex];
                this.Expect(nextScreen);
                this.screenOpener.NavigateTo(nextScreen);
            }
        }
    }
}